﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using LibInterface;
using System.Runtime.Serialization.Formatters.Binary;

namespace PrimesServerLib
{
    public class Controller : IServerLib
    {
        private string _projectPath;
        
        private int _from;
        private int _to;
        private int _granulation;
        private string _returnFile;

        private int _actualPart = 0;

        private int _allParts;

        private int _returnedParts = 0;



        public void Initialize(Stream initConfig, string projectPath)
        {
            _projectPath = projectPath;
            XmlSerializer configReader = new XmlSerializer(typeof(InitConfig));

            var config = (InitConfig)configReader.Deserialize(initConfig);
            this._from = config.From;
            this._to = config.To;
            this._granulation = config.Granulation;
            this._returnFile = config.ReturnFile;

            if (!File.Exists(Path.Combine(_projectPath, this._returnFile)))
            {
                File.CreateText(Path.Combine(_projectPath, this._returnFile));
            }

            _allParts = (this._to - this._from) / _granulation;
        }

        public void Finitialize()
        {
            
        }

        public bool IsCountingOnRun
        {
            get { return true; }
        }

        public bool HasDataWaiting
        {
            get { return this._actualPart < this._allParts; }
        }

        public bool CanGetProgrss
        {
            get { return true; }
        }

        public byte Progress
        {
            get { return (byte)((this._actualPart / this._allParts) * 255); }
        }

        public bool IsDone
        {
            get { return this._returnedParts == this._allParts; }
        }

        public int GetNextDataToCompiutngId()
        {
            return this._actualPart + 1;
        }

        public Compiuting GetDataToCompiuting(int id)
        {
            if (this._actualPart == id - 1)
            {
                this._actualPart++;
            }

            return new Compiuting() { Id = id, ParamitersCount = 1, ParamitersIsDynamic = new bool[] { true }, ParamitersIds = new int[] { id } };
        }

        public LibInterface.Compiuting GetDataToCompiuting()
        {
            
            this._actualPart++;
            return GetDataToCompiuting(this._actualPart);
        }

        public byte[] GetParamiter(int id, bool isDynamic = true)
        {
            var data = new PrimesDTO.Paramiter()
                {
                    From = (id - 1) * this._granulation + this._from,
                    To = id * this._granulation + this._from - 1
                };
            var formater = new BinaryFormatter();
            using (MemoryStream ms = new MemoryStream())
            {
                formater.Serialize(ms, data);
                return ms.ToArray();
            }
        }

        public void GiveDataFromCompiuting(int id, byte[] data)
        {
            
            using(MemoryStream ms = new MemoryStream(data))
            using(StreamWriter fs = new StreamWriter(Path.Combine(_projectPath, this._returnFile))){
                var formater = new BinaryFormatter();
                List<int> listToSave = (List<int>)formater.Deserialize(ms);

                foreach(int prime in listToSave){
                    fs.WriteLine(prime.ToString());
                }
            }
            this._returnedParts++;
        }
    }
}
